package com.gz.logistics.library.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import org.json.JSONObject;

import android.R.bool;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.location.Address;
import android.location.Geocoder;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Base64;
import android.view.View;
import android.view.WindowManager;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;

import com.gz.logistics.library.concurrent.SingleThreadExecutor;


public class Tools {
	private static final String TAG = "Tools";
	public static final String sdCardNotMounted = "没有SD卡";
	public static final String sdCardIsFull = "SD卡已满";
	
	public static boolean hasInternetConnection(Context context) {
		ConnectivityManager conMgr = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (conMgr !=null && conMgr.getActiveNetworkInfo() != null
				&& conMgr.getActiveNetworkInfo().isAvailable()
				&& conMgr.getActiveNetworkInfo().isConnected()) {
			return true;
		} else {
			return false;
		}
	}
	
	public static boolean isWifiAvailable(Context context){
		ConnectivityManager conMgr = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo info = conMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		if(info.isAvailable() && info.isConnected()){
			return true;
		}
		
		return false;
	}
	
	// 获取IMEI码
	public static String getIMEI(Context context) {
		TelephonyManager telephonyManager = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);
		String IMEI = telephonyManager.getDeviceId();
		return IMEI;
	}
	
	/**
	 * 获取本机mac地址
	 * @param context
	 * @return
	 */
	public static String getLocalMacAddress(Context context) {
//		String mac = getWifiMacAddress(5, context);
//		return mac;
		String macAddress = null;
		WifiManager wifiMgr = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
		WifiInfo info = (null == wifiMgr ? null : wifiMgr.getConnectionInfo());
		if (null != info) {
		    macAddress = info.getMacAddress();
		}
		return macAddress;
	}
	
	public static String getWifiMacAddress(int num, Context context){
		String macAddress = "";
		//获取wifi管理器
		final WifiManager wifi = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);  
        if(wifi == null){  
            return macAddress;  
        }  
        
        WifiInfo info = wifi.getConnectionInfo();  
        String macAddress2 = info.getMacAddress();
        if(macAddress2 == null && !wifi.isWifiEnabled()){
        	//尝试多次打开关闭wifi获取mac地址
        	wifi.setWifiEnabled(true);  
            for(int i = 0 ; i < num ; i ++){  
                WifiInfo info2 = wifi.getConnectionInfo();  
                macAddress2 = info2.getMacAddress();  
                if(macAddress2 != null){  
                	CrashHandler.d(TAG, "通过打开wifi获取到mac地址：i = "+i+":"+macAddress2);
                    break;  
                }  
                try {  
                    Thread.sleep(500);  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            }  
            wifi.setWifiEnabled(false);  
        }else if(macAddress2 == null){
        	return macAddress;
        }else{
        	CrashHandler.d(TAG, "直接获取到mac地址："+macAddress2);
        	return macAddress2;
        }
        if(macAddress2 != null){
        	CrashHandler.d(TAG, "通过打开wifi获取到mac地址："+macAddress2);
        	return macAddress2;
        }
		return macAddress;
	}
	
	public static void getFitBitmapByWidth(String path, String result_file,int width) {
		BitmapFactory.Options opt = new BitmapFactory.Options();
		opt.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeFile(path, opt);
		if (opt.outWidth >= width) {
			int s = 1;
			int result_width = opt.outWidth;
			while (result_width >= width) {
				s *= 2;
				result_width = result_width / 2;
			}
			opt.inSampleSize = s;
			opt.inJustDecodeBounds = false;
			bitmap = BitmapFactory.decodeFile(path, opt);
		} else {
			opt.inJustDecodeBounds = false;
			bitmap = BitmapFactory.decodeFile(path, opt);
		}
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(result_file);
			if (null != fos) {
				bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
				fos.flush();
				fos.close();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


	public static double distanceByLngLat(double lng1, double lat1, double lng2,
            double lat2) {
	    double radLat1 = lat1 * Math.PI / 180;
	    double radLat2 = lat2 * Math.PI / 180;
	    double a = radLat1 - radLat2;
	    double b = lng1 * Math.PI / 180 - lng2 * Math.PI / 180;
	    double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
	                    + Math.cos(radLat1) * Math.cos(radLat2)
	                    * Math.pow(Math.sin(b / 2), 2)));
	    s = s * 6378137.0;
	    s = Math.round(s * 10000) / 10000;
	    return s;
	}

	
	/**
	 * 返回当前程序版本名
	 */
	public static String getAppVersionName(Context context) {
		String versionName = "";
		try {
			// ---get the package info---
			PackageManager pm = context.getPackageManager();
			PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
			versionName = pi.versionName;
			if (versionName == null || versionName.length() <= 0) {
				return "";
			}
			
		} catch (Exception e) {
			CrashHandler.e(e);
		}
		return versionName;
	}
	
	/**
	 * 返回当前程序版本号
	 */
	public static int getAppVersionCode(Context context) {
		int versionName = 0;
		try {
			// ---get the package info---
			PackageManager pm = context.getPackageManager();
			PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
			versionName = pi.versionCode;
			
		} catch (Exception e) {
			CrashHandler.e(e);
		}
		return versionName;
	}

	/**
	 * 返回厂商
	 */
	public static String getManufacturer(){
		return Build.MANUFACTURER;
	}
	
	
	/**
	 *  获取手机型号
	 */
	public static String getPhoneType() {
		String model = Build.MODEL;
		return model;
	}

	/**
	 *  获取操作系统版本
	 */
	public static String getPhoneOSVersion() {
		String model = Build.VERSION.RELEASE;
		return model;
	}

	/**
	 *  获取设备ID
	 */
	public static String getDeviceID(Context context) {
		return Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
	}

	public static void hideInputBoard(Activity activity) {
		// 隐藏键盘输入
		IBinder iBinder = null;
		if (activity != null) {
			View view = activity.getCurrentFocus();
			if (view != null) {
				iBinder = view.getWindowToken();
			}
		}
		if (iBinder != null) {
			((InputMethodManager) activity
					.getSystemService(Context.INPUT_METHOD_SERVICE))
					.hideSoftInputFromWindow(iBinder,
							InputMethodManager.HIDE_NOT_ALWAYS);
		}

	}
	
	public static void showInputBoard(Activity activity){
		IBinder iBinder = null;
		View view = null;
		if (activity != null) {
			view = activity.getCurrentFocus();
			if (view != null) {
				iBinder = view.getWindowToken();
			}
		}
		if (iBinder != null) {
			((InputMethodManager) activity
					.getSystemService(Context.INPUT_METHOD_SERVICE))
					.showSoftInput(view,
							InputMethodManager.SHOW_FORCED);
		}
	}

	public static boolean checkEmail(String email) {
		Pattern pattern = Pattern
				.compile("^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$");
		Matcher matcher = pattern.matcher(email);
		if (matcher.matches()) {
			return true;
		}
		return false;
	}

	public static boolean checkUsername(String value) {
//		Pattern pattern = Pattern.compile("^[a-zA-Z0-9.@_]{6,20}$");
//		Matcher matcher = pattern.matcher(value);
//		if (matcher.matches()) {
//			return true;
//		}
		if(value.matches("^[a-zA-Z0-9.@_]{6,20}$")){
			return true;
		} else {
			return false;
		}
	}
	
	public static Bitmap getFitBitmap(String path,int destWidth) {
		File file = new File(path);
		if(!file.exists())
			return null;
		BitmapFactory.Options opt = new BitmapFactory.Options();
		opt.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeFile(path, opt);

		opt.inSampleSize =getFitSample(opt.outWidth,destWidth);
		opt.inPreferredConfig = Bitmap.Config.ARGB_8888; 
		opt.inJustDecodeBounds = false;
		bitmap = BitmapFactory.decodeFile(path, opt);
		return bitmap;
	}
	
	public static int getFitSample(int width, int height, int destWidth, int destHeight){
		int sample = 1;
		while(width>destWidth){
			if(width<destWidth+200){
				break;
			}
			sample = sample*2; 
			width = width/sample;
			height = height/sample;
		}
		
		while(height>destHeight){
			if(height<destHeight+200){
				break;
			}
			sample = sample*2; 
			width = width/sample;
			height = height/sample;
		}
		return sample;
	}
	
	//小图，提供给回复界面和分享界面
	public static int getFitSample1(int width, int height, int destWidth, int destHeight){
		int sample = 1;
		while(width>destWidth){
			if(width<destWidth+50){
				break;
			}
			sample = sample*2; 
			width = width/sample;
			height = height/sample;
		}
		
		while(height>destHeight){
			if(height<destHeight+50){
				break;
			}
			sample = sample*2; 
			width = width/sample;
			height = height/sample;
		}
		return sample;
	}
	
	public static int getFitSample(int width, int destWidth){
		int sample = 1;
		while(width>destWidth){
			sample *= 2;
			width = width/sample;
		}
		
		return sample;
	}
	
	public static void getFitBitmapByWidth(String path, int width) {
		BitmapFactory.Options opt = new BitmapFactory.Options();
		opt.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeFile(path, opt);
		if (opt.outWidth >= width) {
			int s = 1;
			int result_width = opt.outWidth;
			while (result_width >= 800) {
				s *= 2;
				result_width = result_width / 2;
			}
			opt.inSampleSize = s;
			opt.inJustDecodeBounds = false;
			bitmap = BitmapFactory.decodeFile(path, opt);
		} else {
			opt.inJustDecodeBounds = false;
			bitmap = BitmapFactory.decodeFile(path, opt);
		}
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(path);
			if (null != fos) {
				bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
				fos.flush();
				fos.close();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static String saveBitmapAndGetPath(Context context,String path,  Uri uri){
		try {
			BitmapFactory.Options opt = new BitmapFactory.Options();
			opt.inJustDecodeBounds = true;
			Bitmap bitMap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri),null,opt);
			int width = opt.outWidth;
			int height = opt.outHeight;
//			opt.inPreferredConfig = Bitmap.Config.RGB_565; 
			opt.inPreferredConfig = Bitmap.Config.ARGB_8888; 
			opt.inPurgeable = true;
			opt.inInputShareable = true;
			opt.inJustDecodeBounds = false;
			opt.inSampleSize = Tools.getFitSample(width, height, 1080,1080);
			bitMap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri),null,opt);
			
			FileOutputStream fos = null;
			try{
				fos = new FileOutputStream(path);
				if (null != fos) {
//					bitMap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
					bitMap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
					fos.flush();
					fos.close();
				}
			}finally{
				if(bitMap!=null && !bitMap.isRecycled()){
					bitMap.recycle();
				}
			}
			return path;
			
		} catch (Exception e) {
			CrashHandler.e(e);
			return null;
		}
	}
	
	public static String saveBitmapAndGetPath(Context context, String path, Bitmap bitmap){
		try {
			
			FileOutputStream fos = null;
			fos = new FileOutputStream(path);
			if (null != fos) {
				bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
				fos.flush();
				fos.close();
			}
			return path;
			
		} catch (FileNotFoundException e) {
			CrashHandler.e(e);
			return null;
			
		} catch (IOException e) {
			CrashHandler.e(e);
			return null;
			
		} catch (OutOfMemoryError e) {
			CrashHandler.e(e);
			return null;
		}
	}
	
	/**
	 * 保存高质量的图片
	 * @param context
	 * @param outFile
	 * @param uri
	 * @return
	 */
	public static void compressBitmap(Context context,File outFile,  Uri uri){
		try {
			BitmapFactory.Options opt = new BitmapFactory.Options();
			opt.inJustDecodeBounds = true;
			Bitmap bitMap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri),null,opt);
			int width = opt.outWidth;
			int height = opt.outHeight;
			opt.inPreferredConfig = Bitmap.Config.ARGB_8888; 
			opt.inPurgeable = true;
			opt.inInputShareable = true;
			opt.inJustDecodeBounds = false;
			opt.inSampleSize = Tools.getFitSample(width, height, 720,720);
			bitMap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri),null,opt);
			
			FileOutputStream fos = null;
			try{
				fos = new FileOutputStream(outFile);
				if (null != fos) {
					bitMap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
					fos.flush();
					fos.close();
				}
			}finally{
				if(bitMap!=null && !bitMap.isRecycled()){
					bitMap.recycle();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	
	public static void compressBitmap(Context context,Uri outUri,  Bitmap bitmap){
		try {
			
			FileOutputStream fos = null;
			//try{
				fos = new FileOutputStream(outUri.getPath());
				if (null != fos) {
					bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
					fos.flush();
					fos.close();
				}
			//}
//			finally{
//				if(bitmap!=null && !bitmap.isRecycled()){
//					bitmap.recycle();
//				}
//			}
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	
	public static String encode(String s){
    	byte[] s_byte = s.getBytes();
    	String encrypt_key = md5("wzkj205");
    	int ctr = 0;
    	String tmp = "";
    	int string_len = s.length();
    	int encrypt_key_len = encrypt_key.length();
    	byte[] encrypt_key_byte = encrypt_key.getBytes();
    	for(int i = 0;i < string_len; i++) 
    	{
    	   ctr = ctr == encrypt_key_len ? 0 : ctr;	//三元运算
    	   char c = (char)(s_byte[i] ^ encrypt_key_byte[ctr++]);
    	   tmp += c;
    	}
    	tmp = Base64.encodeToString(tmp.getBytes(),Base64.DEFAULT);	// 使用 MIME base64 对数据进行编码
    	return tmp.replace("=", "");
    }
	
	public static String md5(String input){
        String result = input;
        if(input != null) {
            MessageDigest md;
            try {
                md = MessageDigest.getInstance("MD5");
            try {
				md.update(input.getBytes("UTF-8"));
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
            BigInteger hash = new BigInteger(1, md.digest());
            result = hash.toString(16);
            if ((result.length() % 2) != 0) {
                result = "0" + result;
            } 
            }catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
                return null;
            }
        }
        return result;
    }
	
	public static String saveBitmapAndGetPath(Context context,String source_path, String dest_path){
		try {
			BitmapFactory.Options opt = new BitmapFactory.Options();
			opt.inJustDecodeBounds = true;
			Bitmap bitMap = BitmapFactory.decodeFile(source_path,opt);
			int width = opt.outWidth;
			int height = opt.outHeight;
			opt.inPreferredConfig = Bitmap.Config.RGB_565; 
			opt.inPurgeable = true;
			opt.inInputShareable = true;
			opt.inJustDecodeBounds = false;
			opt.inSampleSize = Tools.getFitSample(width, height, 1080,1080);
			bitMap = BitmapFactory.decodeFile(source_path,opt);
			
			FileOutputStream fos = null;
			try{
				fos = new FileOutputStream(dest_path);
				if (null != fos) {
					bitMap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
					fos.flush();
					fos.close();
				}
			}finally{
				if(bitMap!=null && !bitMap.isRecycled()){
					bitMap.recycle();
				}
			}
			return dest_path;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	
	public static String saveBitmapAndGetPath(Context context,String path){
		try {
			BitmapFactory.Options opt = new BitmapFactory.Options();
			opt.inJustDecodeBounds = true;
			Bitmap bitMap = BitmapFactory.decodeFile(path,opt);
			int width = opt.outWidth;
			int height = opt.outHeight;
//			opt.inPreferredConfig = Bitmap.Config.RGB_565; 
			opt.inPreferredConfig = Bitmap.Config.ARGB_8888; 
			opt.inPurgeable = true;
			opt.inInputShareable = true;
			opt.inJustDecodeBounds = false;
			opt.inSampleSize = Tools.getFitSample(width, height, 1080,1080);
			bitMap = BitmapFactory.decodeFile(path,opt);
			
			FileOutputStream fos = null;
			try{
				fos = new FileOutputStream(path);
				if (null != fos) {
					bitMap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
					bitMap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
					fos.flush();
					fos.close();
				}
			}finally{
				if(bitMap!=null && !bitMap.isRecycled()){
					bitMap.recycle();
				}
			}
			return path;
		} catch (Exception e) {
			CrashHandler.e(e);
			return null;
		}
	}

	/**
	 * GPS是否打开
	 */
	public static boolean isGPSOpen(Context context) {
		LocationManager alm = (LocationManager) context
				.getSystemService(Context.LOCATION_SERVICE);
		if (alm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 根据经纬度获取省市名
	 * @param context
	 * @param longitude
	 * @param latitude
	 * @return
	 */
	public static String getPlaceByJW(Context context, Double longitude, Double latitude) {
		Geocoder gc = new Geocoder(context);
		List<Address> addresses = null;
		try {
			addresses = gc.getFromLocation(latitude,
					longitude, 1);
			if (addresses.size() > 0) {
				return addresses.get(0).getAdminArea() + ","
						+ addresses.get(0).getLocality();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static boolean isSdCardMounted() {
		if (Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {
			return true;
		} else {
			return false;
		}
	}

	public static int formatNowTime(Context context){
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		return Integer.parseInt(sdf.format(date));
	}
	
	private static SimpleDateFormat FULL_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault());
	private static SimpleDateFormat SHORT_FORMAT = new SimpleDateFormat("yyyy-MM-dd",Locale.getDefault());
	private static SimpleDateFormat CHINESE_FORMAT = new SimpleDateFormat("yyyy年MM月dd日",Locale.getDefault());
	
	/**
	 * 
	 * @param when 单位秒
	 * @param fullFormat
	 * @return
	 */
	public static String formatDatetime(long when,boolean fullFormat) {
		// when是时间戳，单位是秒，直接创建一个Date类型的对像，把时间表戳传进来
		Date date = new Date(when * 1000);
		if (fullFormat) {
			return FULL_FORMAT.format(date);
		} else {
			
			return SHORT_FORMAT.format(date);
		}
	}
	
	public static String format2ChineseDate(long when) {
		// when是时间戳，单位是秒，直接创建一个Date类型的对像，把时间表戳传进来
		Date date = new Date(when * 1000);
		return CHINESE_FORMAT.format(date);
	}
	
	public static String formatDatetime(long when) {
		return formatDatetime(when,false);
	}
	
	/**
	 * 
	 * @param context
	 * @param when 单位秒
	 * @param fullFormat
	 * @return
	 */
	public static String formatTimeStampString(Context context, long when,
			boolean fullFormat) {
		// when是时间戳，单位是秒，直接创建一个Date类型的对像，把时间表戳传进来
		Date date = new Date(when * 1000);
		Date now = new Date();
		if (fullFormat) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
			return sdf.format(date);
		}
		// If the message is from a different year, show the date and year.
		if (date.getYear() != now.getYear()) {
			SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd");
			return sdf.format(date);
		}else if(date.getMonth() != now.getMonth()){
			if(date.getDay()+1==now.getDay() && now.getTime()-date.getTime()<7*24*60*60*1000){
				SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
				return "昨天 " + sdf.format(date);
			}else if(date.getDay()+2==now.getDay() && now.getTime()-date.getTime()<7*24*60*60*1000){
				SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
				return "前天 " + sdf.format(date);
			}else{
				SimpleDateFormat sdf = new SimpleDateFormat("MM/dd HH:mm");
				return sdf.format(date);
			}
		}else if (date.getDay() == now.getDay()) {
			if(now.getTime()-date.getTime()<7*24*60*60*1000){
				SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
				return "今天 "+sdf.format(date);
			}else{
				SimpleDateFormat sdf = new SimpleDateFormat("MM/dd HH:mm");
				return sdf.format(date);
			}
			// If it is from a different day than today, show only the date.
		} else {
			if(date.getDay()+1==now.getDay() && now.getTime()-date.getTime()<7*24*60*60*1000){
				SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
				return "昨天 " + sdf.format(date);
			}else if(date.getDay()+2==now.getDay() && now.getTime()-date.getTime()<7*24*60*60*1000){
				SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
				return "前天 " + sdf.format(date);
			}else{
				SimpleDateFormat sdf = new SimpleDateFormat("MM/dd HH:mm");
				return sdf.format(date);
			}
		}
	}


	public static String getDiffByTimeStampString(long when) {
		// when是时间戳，单位是秒，直接创建一个Date类型的对像，把时间表戳传进来

        final long getTime = when * 1000;

        final long currTime = System.currentTimeMillis();
        final Date formatSysDate = new Date(currTime);

        // 判断当前总天数
        final int sysMonth = formatSysDate.getMonth() + 1;
        final int sysYear = formatSysDate.getYear();

        // 计算服务器返回时间与当前时间差值
        final long seconds = (currTime - getTime) / 1000;
        final long minute = seconds / 60;
        final long hours = minute / 60;
        final long day = hours / 24;
        final long month = day / calculationDaysOfMonth(sysYear, sysMonth);
        final long year = month / 12;
        if(year>0){
        	return year + "年前";
        }else if(month > 0){
        	return month + "月前";
        }else if (day > 0) {
        	return day + "天前";
        } else if (hours > 0) {
            return hours + "小时前";
        } else if (minute > 0) {
            return minute + "分钟前";
        } else if (seconds > 0) {
            return "1" + "秒前";
            // return seconds + context.getString(R.string.str_secondago);
        } else {
//	          return "1" + context.getString(R.string.str_secondago);
            return "1" + "分钟前"; //都换成分钟前
        }
	}
	
	/**
     * 计算月数
     * 
     * @return
     */
    private static int calculationDaysOfMonth(int year, int month) {
        int day = 0;
        switch (month) {
        // 31天
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            day = 31;
            break;
        // 30天
        case 4:
        case 6:
        case 9:
        case 11:
            day = 30;
            break;
        // 计算2月天数
        case 2:
            day = year % 100 == 0 ? year % 400 == 0 ? 29 : 28
                    : year % 4 == 0 ? 29 : 28;
            break;
        }

        return day;
    }
    
	public static String getFullDateFromStampString(Context context, long when) {
		// when是时间戳，单位是秒，直接创建一个Date类型的对像，把时间表戳传进来
		Date date = new Date(when * 1000);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
		return sdf.format(date);
	}
	
	public static int getFullDateFromStampString(long when) {
		// when是时间戳，单位是秒，直接创建一个Date类型的对像，把时间表戳传进来
		Date date = new Date(when * 1000);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		return Integer.parseInt(sdf.format(date));
	}
	
	public static String formatBaoBaoStampString(Context context, long when,
			boolean fullFormat) {
		// when是时间戳，单位是秒，直接创建一个Date类型的对像，把时间表戳传进来
		Date date = new Date(when * 1000);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		long l = System.currentTimeMillis() - calendar.getTimeInMillis();
		Calendar result_calendar = Calendar.getInstance();
		result_calendar.setTimeInMillis(l);
		int year = result_calendar.get(Calendar.YEAR) - 1970;
		int month = result_calendar.get(Calendar.MONTH);
		int day = result_calendar.get(Calendar.DAY_OF_MONTH);
		if (year == 0 && month == 0 && day==0) {
			return "";
		}else{
			if(year == 0 && month == 0){
				return day>0?day + "天":"";
			}else{
				return (year>0?year + "岁":"") + (month>0?month + "个月":"");
			}
		}
	}

	public static String formatYuChangStampString(Context context, long when,
			boolean fullFormat) {
		// when是时间戳，单位是秒，直接创建一个Date类型的对像，把时间表戳传进来
		Date date = new Date(when * 1000);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		long l = calendar.getTimeInMillis() - System.currentTimeMillis();
		Calendar result_calendar = Calendar.getInstance();
		result_calendar.setTimeInMillis(l);
		int month = 10 - result_calendar.get(Calendar.MONTH);
		if(month<=0){
			return 10 + "月";
		}
		return month + "月";
	}

	public static void scalePic(Bitmap bitmap, int sWidth, String filePath) {
		int bmpWidth = bitmap.getWidth();

		int bmpHeight = bitmap.getHeight();
		float scale_rate = 1;
		// 缩放图片的尺寸
		if (sWidth > bmpWidth) {
			scale_rate = 1;
		} else {
			scale_rate = sWidth / bmpWidth;
		}
		
		Matrix matrix = new Matrix();

		matrix.postScale(scale_rate, scale_rate);

		// 产生缩放后的Bitmap对象

		Bitmap resizeBitmap = Bitmap.createBitmap(bitmap, 0, 0, bmpWidth,
				bmpHeight, matrix, false);
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(filePath);
			if (null != fos) {
				resizeBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
				fos.flush();
				fos.close();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		resizeBitmap.recycle();
		bitmap.recycle();
	}

	public static int px2dip(Context context, float pxValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (pxValue / scale + 0.5f);
	}

	public static int dip2px(Context context, float dipValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (dipValue * scale + 0.5f);
	}
	
	public static int sp2px(Context context, float spValue) {  
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;  
        return (int) (spValue * fontScale + 0.5f);  
    }
	
	public static int px2sp(Context context, float pxValue) {  
	    final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;  
	    return (int) (pxValue / fontScale + 0.5f);  
	} 

	public static void copyFile(File sourceFile, File targetFile) {
		// 新建文件输入流并对它进行缓冲
		FileInputStream input;
		try {
			input = new FileInputStream(sourceFile);
			BufferedInputStream inBuff = new BufferedInputStream(input);
			// 新建文件输出流并对它进行缓冲
			FileOutputStream output = new FileOutputStream(targetFile);
			BufferedOutputStream outBuff = new BufferedOutputStream(output);
			// 缓冲数组
			byte[] b = new byte[1024 * 5];
			int len;
			while ((len = inBuff.read(b)) != -1) {
				outBuff.write(b, 0, len);
			}
			// 刷新此缓冲的输出流
			outBuff.flush();

			// 关闭流
			inBuff.close();
			outBuff.close();
			output.close();
			input.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}	
    
	public static boolean isFolderExist(String dirName){
		File file = new File(dirName);
		if(!file.exists()){
			return file.mkdirs();
		}
		
		return true;
	}
	
	/**
	 * 获取指定名字的文件夹绝对路径,传人的文件名包括斜杠"/",传人null表示获取根目录(SD卡或者程序根目录)
	 * @param context
	 * @param dirName
	 * @return
	 */
	public static String obtainDirPath(Context context, String dirName){
		if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
			if(null == dirName || "".equals(dirName)){
				return Environment.getExternalStorageDirectory().getAbsolutePath();
			}
			String path = Environment.getExternalStorageDirectory().getAbsoluteFile()
					+ Constants.FOLDER_ROOT + dirName;
			if(isFolderExist(path)){
				return path;
			}
		
		}else /*if(!APK_DOWNLOAD_FOLDER.equals(dirName))*/{
			//这句创建_app_bulogame
			File dir = context.getDir(dirName, Context.MODE_PRIVATE);
			if(isFolderExist(dir.getAbsolutePath())){
				return dir.getAbsolutePath();
			}
		}
		
		return null;
	}
	
	
	public static int[] fixPictureSize(int width, int height, int mScaleWidth){
		int[] fixSize = new int[2];
		if(width > mScaleWidth){
			int dValue = width - mScaleWidth;
			fixSize[0] = width - dValue;
			fixSize[1] = height - dValue;
			
			if(fixSize[0] <= 0 || fixSize[1] <= 0){
				float off = Float.valueOf(width) / Float.valueOf(fixSize[0]);
				fixSize[1] = (int) (height / off);
			}
		
		}else{
			fixSize[0] = width;
			fixSize[1] = height;
		}
		
		CrashHandler.d(TAG, "fix宽" + fixSize[0] + "fix高" + fixSize[1]);
		
		return fixSize;
	}
	
	private final static double EARTH_RADIUS =6371.004;
	private final static double DEF_PI180= 0.01745329252;
	/**
	 * 获取两个经纬度间的距离，返回值为千米
	 * @param lat1 自己的lat
	 * @param lng1
	 * @param lat2 对方的lat
	 * @param lng2
	 * @return
	 */
	public static double getDistance(double lat1, double lng1, double lat2, double lng2)
	{
	   double radLat1 = lat1 * DEF_PI180;//rad(lat1);
	   double radLat2 = lat2 * DEF_PI180;//rad(lat2);
	   double radLng1 = lng1 * DEF_PI180;
	   double radLng2 = lng2 * DEF_PI180;
	   double distanceLat = radLat1 - radLat2;
	   double distanceLng = radLng1 - radLng2;

	   double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(distanceLat/2),2) + 
			   Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(distanceLng/2),2)));
	   s = s * EARTH_RADIUS;
	   s = Math.round(s * 1000000000000000.00) / 1000000000000000.00;
	   
	   CrashHandler.d(TAG, "距离 " + s);
	   
	   return s;
	}
	

	/**
	 * 读取byte数组指定位置的内容
	 * 
	 * @param src 被读取的数组
	 * @param pos 读取的起始位置	
	 * @param len 读取数据的长度
	 * @return
	 */
	public static byte[] readBytesArray(byte[] src, int pos, int len) {
		byte[] ret = new byte[len];
		System.arraycopy(src, pos, ret, 0, len);
		return ret;
	}
	
	
	/**
	 * 记录用户行为
	 */
	public static void recordBehavious(final Context context, final String tag, 
			final String behavious, final long timestamp){
		SingleThreadExecutor.getInstance().execute(new Runnable() {
			
			@Override
			public void run() {
				CrashHandler.d(TAG, "线程" + Thread.currentThread().getName() + "开始执行");
				FileWriter writer = null;
				try{
					String reportDir = Tools.obtainDirPath(context, Constants.FOLDER_REPORT_CACHE);
					final File behaviousFile = new File(reportDir + Constants.FILE_BEHAVIOUS_REPORT);
					if(!behaviousFile.exists()){//用户行为文件不存在
						behaviousFile.createNewFile();
						CrashHandler.d(TAG, "创建用户行为统计log");
					}
					
					StringBuilder sb = new StringBuilder();
					sb.append(tag + "|")
//					.append(new Date(timestamp).toLocaleString() + "|")
					.append(timestamp + "|")
					.append(behavious + "|")
					.append(getIMEI(context) + "|")
					.append(getLocalMacAddress(context) + "|")
					.append(getManufacturer() + "|")
					.append(getPhoneType() + "|")
					.append(getPhoneOSVersion() + "|")
					.append(getDeviceID(context) + "|")
					.append(getAppVersionName(context) + "|")
					.append(context.getPackageName())
//					.append(Global.get().getUserinfo() == null ? 0 : Global.get().getUserinfo().getUid() + "|")
//					.append(GlobalData.get().getUserinfo().getUsername())
					;
					
					writer = new FileWriter(behaviousFile, true);//这句执行过后文件变空
					writer.write(sb.toString() + "\n");
					
				}catch(Exception e){
					CrashHandler.e(e);
				
				}finally {
					try {
						writer.flush();
						writer.close();
						
					} catch (Exception e2) {
						CrashHandler.e(e2);
					}
					CrashHandler.d(TAG, "线程" + Thread.currentThread().getName() + "执行完毕");
				}
				
			}
		});
		
	}
	
	/**
	 * 获取用户行为字符串
	 * @return 
	 */
	public static String getRecordBehaviousString(final Context context, final String tag, 
			final String behavious, final long timestamp){
			
			StringBuilder sb = new StringBuilder();
			sb.append(tag + "|")
//			.append(new Date(timestamp).toLocaleString() + "|")
			.append(timestamp + "|")
			.append(behavious + "|")
			.append(getIMEI(context) + "|")
			.append(getLocalMacAddress(context) + "|")
			.append(getManufacturer() + "|")
			.append(getPhoneType() + "|")
			.append(getPhoneOSVersion() + "|")
			.append(getDeviceID(context) + "|")
			.append(getAppVersionName(context) + "|")
			.append(context.getPackageName() + "|");
//			.append(Global.get().getUserinfo() == null ? 0 : Global.get().getUserinfo().getUid() + "|");
//			.append(GlobalData.get().getUserinfo().getUsername())
			
			return sb.toString();
		
	}
	
	
	/**
	 * 记录用户行为
	 */
	public static void recordBehavious1(Context context, String tag){
		FileReader reader = null;
		FileWriter writer = null;
		try{
			String reportDir = Tools.obtainDirPath(context, Constants.FOLDER_REPORT_CACHE);
			final File behaviousFile = new File(reportDir + Constants.FILE_BEHAVIOUS_REPORT);
			if(!behaviousFile.exists()){//用户行为文件不存在
				behaviousFile.createNewFile();
//				return;
				CrashHandler.d(TAG, "创建用户行为统计log");
			}
			reader = new FileReader(behaviousFile);
			StringBuilder sBuilder = new StringBuilder();
			int len = -1;
			char[] buf = new char[1024]; 
			while((len = reader.read(buf)) != -1){
				sBuilder.append(buf, 0, len);
			}
			
			JSONObject json;
			if(sBuilder.toString() == null || "".equals(sBuilder.toString())){
				String[] tags = obtainTags();
				//无用户行为信息,构建一个
				json = new JSONObject();
				for(int i = 0; i < tags.length; i++){
					if(tags[i].equals(tag)){
						json.put(tag, 1);
					}else {
						json.put(tags[i], 0);//初始化所有tag
					}
				}
//				return;
			
			}else {
				json = new JSONObject(sBuilder.toString());
				int count = json.getInt(tag);
				json.put(tag, count + 1);
			}

			writer = new FileWriter(behaviousFile);//这句执行过后文件变空
			writer.write(json.toString());
			writer.flush();
			
		}catch(Exception e){
			CrashHandler.e(e);
		
		}finally {
			try {
				reader.close();
				writer.close();
				
			} catch (Exception e2) {
				CrashHandler.e(e2);
			}
		}
	}
	
	private static String[] obtainTags(){
//		return new String[]{
//				Dynamic.TAG,
//				GameDiscuz.TAG,
//				InvitationDetail.TAG,
//				CommunityMember.TAG,
//		};
		return null;
	}
	
	public static boolean checkPackageName(Context context, String packageName){
		PackageManager pm = context.getPackageManager();
		List<PackageInfo> infos = pm.getInstalledPackages(0);
		for(PackageInfo info : infos){
			if(info.packageName.equals(packageName)){
				return true;
			}
		}
		
		return false;
	}



	
	public static boolean closeInputStream(InputStream inStream){
		try {
			if(inStream != null)
				inStream.close();
			return true;
		} catch (IOException e) {
			CrashHandler.e(e);
			return false;
		}
	}
	
	public static boolean closeOutputStream(OutputStream outStream){
		try {
			if(outStream != null)
				outStream.close();
			return true;
		} catch (IOException e) {
			CrashHandler.e(e);
			return false;
		}
	}
	
	public static boolean closeReader(Reader reader){
		try {
			if(reader != null)
				reader.close();
			return true;
		} catch (IOException e) {
			CrashHandler.e(e);
			return false;
		}
	}
	
	public static boolean closeWriter(Writer writer){
		try {
			if(writer != null)
				writer.close();
			return true;
		} catch (IOException e) {
			CrashHandler.e(e);
			return false;
		}
	}
	
	public static boolean checkFileExist(File file){
		try{
			if(!file.exists()){
				return file.createNewFile();
			}
		}catch(Exception e){
			CrashHandler.e(e);
			return false;
		}
		
		return true;
	}
	
	/**
	 * 获取文件夹使用大小
	 * @param dirName 文件夹名
	 * @return 文件夹大小(单位byte)
	 */
	public static long getDirUsedSize(String dirName){
		long usedSize = 0;
		File dir = new File(dirName);
		if(dir.isDirectory()){
			for(File file : dir.listFiles()){
				usedSize += file.length();
			}
		}
		
//		BigDecimal decimal = new BigDecimal(usedSize / 1024f / 1024f);
//		float usedByteSize = decimal.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();

//		CrashHandler.d(TAG, "文件数：" + dir.listFiles().length);
//		CrashHandler.d(TAG, "文件夹大小：" + usedSize);
		
		return usedSize;
	}

	
	/**
	 * 解压zip文件
	 * @param fileName zip文件名
	 * @throws ZipException
	 * @throws IOException
	 */
	public static void unzipFile(String fileName) throws ZipException, IOException{
		int BUFFER_SIZE = 1024;
		File file = new File(fileName);
		if(file.exists()){
			//创建目录
			File saveDir = null;
			String parentDir = file.getParent();
			if(parentDir != null){
				saveDir = new File(parentDir, file.getName().substring(0, file.getName().lastIndexOf(".")));
				saveDir.mkdirs();
			}
			ZipFile zipFile = new ZipFile(file);
			try{
				Enumeration<? extends ZipEntry> entrys = zipFile.entries();
				while(entrys.hasMoreElements()){
					ZipEntry entry = entrys.nextElement();
					BufferedInputStream bufferIn = new BufferedInputStream(zipFile.getInputStream(entry));
					BufferedOutputStream bufferOut = new BufferedOutputStream(
							new FileOutputStream(saveDir.getAbsolutePath() + "/" + entry.getName()), 
							BUFFER_SIZE);
					byte[] buf = new byte[BUFFER_SIZE];
					int readCount;
					try{
						while((readCount = bufferIn.read(buf)) != -1){
							bufferOut.write(buf, 0, readCount);
						}
					} finally{
						bufferIn.close();
						bufferOut.close();
					}
					
				} 
			}finally{
				zipFile.close();
			}
		}
	}
	
	/**
	 * 缩放图片到期望的大小
	 * @param rowWidth 原始图片宽
	 * @param rowHight 原始图片高
	 * @param maxWidth 允许图片缩放到的最大宽度
	 * @return 缩放后的宽高。int[0]宽、int[1]高
	 */
	public static int[] fixSize(int rowWidth, int rowHight, int maxWidth){
		CrashHandler.d(TAG, "原始宽" + rowWidth);
		CrashHandler.d(TAG, "原始高" + rowHight);
		int[] size = new int[2];
		if(rowWidth >= maxWidth){//图片宽大于最大宽，则缩小图片宽到maxWidth
			double off = Double.valueOf(rowWidth) / Double.valueOf(maxWidth);
			double height = rowHight / off;
			size[0] = maxWidth;
			size[1] = (int) height;
		
		}else {//原图显示
			size[0] = rowWidth;
			size[1] = rowHight;
			
		}
		
		return size;

	}
	

	public static void measureView(View view) {
		ViewGroup.LayoutParams p = view.getLayoutParams();
		if (p == null) {
			p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
		}
		int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
		int lpHeight = p.height;
		int childHeightSpec;
		if (lpHeight > 0) {
			childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
					MeasureSpec.EXACTLY);
		} else {
			childHeightSpec = MeasureSpec.makeMeasureSpec(0,
					MeasureSpec.UNSPECIFIED);
		}
		view.measure(childWidthSpec, childHeightSpec);
	}
	
	
	public static ProgressDialog showProgressDialog(Context context, String title, String message) {
		 return ProgressDialog.show(context, title, message, true, false);
	}
	
	public static String Base64Encode(String value) {
		return Base64.encodeToString(value.getBytes(), Base64.DEFAULT);
	}
	
	/**
	 * 将arg1合并到arg0, 
	 * @param arg0
	 * @param arg1
	 */
	public static <T> void merge(List<T> arg0,List<T> arg1,Comparator<T> c){
		merge(arg0,arg1,c,false);
	}

    /**
	 * 两个集合之间差集, 去重并排序
	 * @param
	 */
	public static <T> void merge(List<T> arg0,List<T> arg1,Comparator<T> c, boolean reverse){
		if (arg0 == null || arg1 == null) {
			return;
		}
		
		TreeSet<T> set = null;
		if(c != null){
			set = new TreeSet<T>(c);
		} else {
			set = new TreeSet<T>();
		}
		for(T t : arg0){
			set.add(t);
		}
		for(T t : arg1){
			set.add(t);
		}
		arg0.clear();
		arg0.addAll(set);
		set.clear();
		set=null;
		
		if(reverse){
			Collections.reverse(arg0);
		}
	}
	
	public static String getChannelName(Context mContext){
		ApplicationInfo appInfo = null;
		try {
			appInfo = mContext.getPackageManager().getApplicationInfo(mContext.getPackageName(), PackageManager.GET_META_DATA);
		} catch (NameNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if(appInfo != null){
			return appInfo.metaData.getString("InstallChannel");
		}
		
		return "";
	}
	public static boolean checkPhone(String number){
		if(TextUtils.isEmpty(number)){
		    return false;
	    }else{
	    	Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$");
			Matcher m = p.matcher(number);
			return m.matches();
	    }
	}
	
	public static int getScreenWidth(Context context){
		WindowManager wm = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
			    return wm.getDefaultDisplay().getWidth();
	}
	public static int getScreentHeight(Context context){
		WindowManager wm = (WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE);
		return wm.getDefaultDisplay().getHeight();
	}
	public static boolean isNullOrEmpty(Object object){
		if (object==null) {
			return false;
		}else if (object.equals("")) {
			return false ;
		}else {
			return true;
		}
		
		
	}
	public static  Boolean isNumberic(String message)
	{
	     
	        if(message.matches("[0-9]+"))
	        {
	        
	            return true;
	        }
	        else
	            return false;
	}
}